package com.spider.util;

import java.util.Arrays;
import java.util.OptionalDouble;
import java.util.Scanner;

/**
 * Created by Ruan on 2017/9/11.
 */
public class GreyCorrelation {
	
	/*灰色关联算法*/
	public static double[] greyCorrelationMethod(double data[][]){

		double[][] nondim = nondim(data);
		double[] result = greyRelativeCoe(nondim);
		return result;
	}

	/*指标无量纲化（离差标准化）*/
	public static double[][] nondim (double[][] datas) {
		int column=datas.length;
		int row=datas[0].length;
		double nondim[][]=new double[column][row];

		for (int i = 0; i < row ; i++) {
			double[] rows = new double[column];
			for (int j = 0; j <column; j++) {
				rows[j] = datas[j][i];
			}
			double featureMax = Arrays.stream(rows).max().getAsDouble();
			double featureMin = Arrays.stream(rows).min().getAsDouble();
			for (int j = 0; j <column; j++) {
				nondim[j][i] = (datas[j][i]-featureMin)/(featureMax-featureMin);
			}
		}
		return nondim;
	}
	public static double[] greyRelativeCoe(double[][] datas){
		int column=datas.length;
		int row=datas[0].length;
		/*最优序列*/
		double optSeq[] ={1,0,0};
		/*权重*/
		double weight[] = {6,3,2};
		/*序列差*/
		double delta[][] = new double[column][row];
		/*属性关联系数*/
		double coeAttRelation[][] = new double[column][row];
		/*关联系数*/
		double result[] = new double[column];
		for (int i = 0; i <column ; i++) {
			for (int j = 0; j <row ; j++) {
				delta[i][j] = Math.abs(datas[i][j] - optSeq[j]);
			}
		}
		/*两级最大差*/
		double featureMax = delta[0][0];
		for (double[] doubles : delta){
			double tempMax = Arrays.stream(doubles).max().getAsDouble();
			featureMax = max(featureMax,tempMax);
		}
		/*两级最小差*/
		double featureMin = delta[0][0];
		for (double[] doubles : delta){
			double tempMin = Arrays.stream(doubles).min().getAsDouble();
			featureMin = min(featureMin,tempMin);
		}
		/*每个属性的关系系数*/
		for (int i = 0; i <column ; i++) {
			for (int j = 0; j <row ; j++) {
				coeAttRelation[i][j] = (featureMin + 0.5*featureMax)/(delta[i][j] + 0.5*featureMax);
			}
		}
		for (int i = 0; i <column ; i++) {
			double res = 0;
			for (int j = 0; j <row ; j++) {
				res+= coeAttRelation[i][j] / weight[j];
			}
			result[i] = res;
		}
		return result;
	}
	public static double max(double i,double j)
	{
		return i>j?i:j;
	}
	public static double min(double i,double j)
	{
		return i>j?j:i;
	}

	public static void main(String args[]){
		double [][] X = {
				{8.50,1490,21006.99},
				{9.50,2130,12001.88},
				{14.00,1760,25967.01},
				{8.4,1960,25684.91},
				{14.01,2130,24231.67}
		};
		double[][] nondim = nondim(X);
		double[] result = greyRelativeCoe(nondim);

		double distance = GetDistance(120.227155, 30.325279, 120.224377, 30.307859);
		System.out.println(distance);
	}


	private static final double EARTH_RADIUS = 6378.137;

	private static double rad(double d){
		return d * Math.PI / 180.0;
	}

	public static double GetDistance(double long1, double lat1, double long2, double lat2) {
		double a, b, d, sa2, sb2;
		lat1 = rad(lat1);
		lat2 = rad(lat2);
		a = lat1 - lat2;
		b = rad(long1 - long2);

		sa2 = Math.sin(a / 2.0);
		sb2 = Math.sin(b / 2.0);
		d = 2   * EARTH_RADIUS
				* Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1)
				* Math.cos(lat2) * sb2 * sb2));
		return d*1000;
	}
}
